/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
// SOME MATERIAL ADAPTED FROM:
/*******************************************************************************
 * Copyright (c) 2004, 2005 Elias Volanakis and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * Elias Volanakis - initial API and implementation
 ?******************************************************************************/

package org.apache.pig.pigpen.editor;

import java.util.EventObject;

import org.apache.pig.pigpen.LoggerUtil;
import org.apache.pig.pigpen.editor.model.Query;
import org.apache.pig.pigpen.editor.textEditor.PigScriptEditor;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.gef.commands.CommandStackListener;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.EditorPart;
import org.eclipse.ui.part.MultiPageEditorPart;

public class PigPenEditor extends MultiPageEditorPart implements
        CommandStackListener, ISelectionListener {

    private TableViewer headerPage;
    
    private PigQueryEditor queryPage;

    private PigScriptEditor scriptPage;

    private boolean showMessage = true;

    public PigPenEditor() {
    	
    }

    @Override
    protected void createPages() {
        createQueryPage();
        createHeaderPage();
        createTextEditor();

        initHeaderContent();
        initHeaderEditors();

        updateTitle();
    }

    void createQueryPage() {
        try {
            queryPage = new PigQueryEditor(this);
            int index = addPage(queryPage, getEditorInput());
            setPageText(index, "Operator Graph");
        } catch (PartInitException e) {
            LoggerUtil.logError("Error creating nested editor", e);
        }
    }

    void createHeaderPage() {
        headerPage = new TableViewer(getContainer());
        int index = addPage(headerPage.getControl());
        setPageText(index, "Header");
    }

    void createTextEditor() {
        scriptPage = new PigScriptEditor(this);
        try {
            int index = addPage(scriptPage, getEditorInput());
            setPageText(index, "Pig Script");
        } catch (PartInitException e) {
            LoggerUtil.logError("Error creating nested editor", e);
        }

    }

    void updateTitle() {
        IEditorInput input = getEditorInput();
        setPartName(input.getName());
        setTitleToolTip(input.getToolTipText());
    }

    public void setFocus() {
        switch (getActivePage()) {
        case 0:
            queryPage.setFocus();
            if (scriptPage.isDirty() && showMessage) {
                showMessageBox("Please save the query to see the corresponding changes in the graph.");
                showMessage = false;
            }
            break;
        case 1:
            headerPage.getTable().setFocus();

            break;
        case 2:
            scriptPage.setFocus();
            break;
        }
    }

    private void showMessageBox(String str) {
        MessageBox box = new MessageBox(getSite().getShell());
        box.setMessage(str);
        box.open();
    }

    void initHeaderContent() {

        Table table = headerPage.getTable();
        table.setHeaderVisible(true);
        table.setLinesVisible(true);

        // associate a single column with the table
        TableColumn col = new TableColumn(table, SWT.LEFT);
        col.setText("Header Items");
        col.setWidth(600);

        headerPage.setLabelProvider(new HeaderLabelProvider());
        headerPage.setContentProvider(new HeaderContentProvider());

        refreshHeaderPage();
    }

    public void refreshHeaderPage() {
        headerPage.setInput(getQuery()); // invoking "setInput()" again causes
        // the page to refresh itself
    }

    void initHeaderEditors() {
        final TextCellEditor editor = new TextCellEditor(headerPage.getTable());
        headerPage.setCellEditors(new CellEditor[] { editor });
        headerPage.setCellModifier(new HeaderCellModifier(this, headerPage));
        headerPage.setColumnProperties(new String[] { "HeaderItem" });
    }

    void initTextEditor() {

    }

    public void doSave(IProgressMonitor monitor) {
        // queryPage.doSave(monitor);
        if (scriptPage.isDirty())
            scriptPage.doSave(monitor);
        queryPage.initializeGraphicalViewer();

        queryPage.doSave(monitor);
    }

    public void gotoMarker(IMarker marker) {
        // TODO ...
    }

    public boolean isSaveAsAllowed() {
        return false; // TODO: will want to enable Save-As later
    }

    public void doSaveAs() {
        // TODO: later, when we enable Save-As, need to implement this method
        throw new UnsupportedOperationException("Save-As not supported");
    }

    private Query getQuery() {
        return queryPage.getQuery();
    }

    // ------------------------

    /**
     * Initializes the editor.
     */
    public void init(IEditorSite site, IEditorInput input)
            throws PartInitException {
        // store site and input
        setSite(site);
        setInput(input);

        // add CommandStackListener
        // getCommandStack().addCommandStackListener(this);

        // add selection change listener
        getSite().getWorkbenchWindow().getSelectionService()
                .addSelectionListener(this);

        super.init(site, input);
    }

    /**
     * Indicates if the editor has unsaved changes.
     * 
     * @see EditorPart#isDirty
     */
    public boolean isDirty() {
        return queryPage.isDirty() || scriptPage.isDirty();
    }

    public void commandStackChanged(EventObject event) {
        switch (getActivePage()) {
        case 0:
            queryPage.commandStackChanged(event);
            break;
        case 1:
            // headerPage.commandStackChanged(event);
            break;
        // case 2 :
        // textEditor
        }
    }

    public void selectionChanged(IWorkbenchPart part, ISelection selection) {
        switch (getActivePage()) {
        case 0:
            queryPage.selectionChanged(part, selection);
            break;
        case 1:
            // headerPage.selectionChanged(part, selection);
            break;

        }
    }

//    public static PigServer initPigServer() {
//        IPreferenceStore store = PigPenPlugin.getDefault()
//                .getPreferenceStore();
//        String stringList = store.getString(PreferenceConstants.P_PROPERTIES);
//        Map<String, String> PrefProperties = PluginConfiguration
//                .parseString(stringList);
//        String confPath = PrefProperties.get(PreferenceConstants.P_CONFPATH);
//        ConsoleLogger logger = ConsoleLogger.getDefault();
//        PigServer pigServer = null;
//        String JOB_TRACKER_LOCATION = "mapred.job.tracker";
//        String FILE_SYSTEM_LOCATION = "fs.default.name";
//
//        if (confPath == null) {
//            logger.clear();
//            logger.setFocus();
//            logger
//                    .error("Please set the ConfigurationPath variable in Pig Preferences (Window -> Preferences -> Pig) to point to the directory containing hadoop-site.xml and pig.properties");
//            return pigServer;
//        }
//        logger.clear();
//        if (confPath.charAt(confPath.length() - 1) != '/')
//            confPath = confPath + "/";
//
//        try {
//
//            FileInputStream input = new FileInputStream(new File(confPath
//                    + "pig.properties"));
//            Properties sysProperties = new Properties();
//            sysProperties.load(input);
//            for (Entry<Object, Object> e : sysProperties.entrySet()) {
//                System.setProperty((String) e.getKey(), (String) e.getValue());
//            }
//            Configuration conf = new Configuration();
//            conf.addResource((new File(confPath + "hadoop-site.xml")).toURI()
//                    .toURL());
//
//            Properties properties = ConfigurationUtil.toProperties(conf);
//
//            pigServer = new PigServer(ExecType.MAPREDUCE, properties);
//
//            //System.out.println(pigContext.getDfs().getStatistics().toString())
//            // ;
//        } catch (Throwable e) {
//            // logger.setFocus();
//            logger.error(e.getMessage());
//            logger
//                    .error("Please set the ConfigurationPath variable in Pig Preferences (Window -> Preferences -> Pig) to point to the directory containing hadoop-site.xml and pig.properties");
//        }
//        PigContext pigContext = pigServer.getPigContext();
//        // logger.setFocus();
//        // logger.info("Connected to map-reduce job tracker at: " +
//        // pigContext.getProperties().getProperty(JOB_TRACKER_LOCATION));
//        // logger.info("Connected to hadoop file system at: " +
//        // pigContext.getProperties().getProperty(FILE_SYSTEM_LOCATION));
//        return pigServer;
//    }

}